{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 一、导入工具包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二、读取数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pregnants</th>\n",
       "      <th>Plasma_glucose_concentration</th>\n",
       "      <th>blood_pressure</th>\n",
       "      <th>Triceps_skin_fold_thickness</th>\n",
       "      <th>serum_insulin</th>\n",
       "      <th>BMI</th>\n",
       "      <th>Diabetes_pedigree_function</th>\n",
       "      <th>Age</th>\n",
       "      <th>Target</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.639947</td>\n",
       "      <td>0.866045</td>\n",
       "      <td>-0.031990</td>\n",
       "      <td>0.670643</td>\n",
       "      <td>-0.181541</td>\n",
       "      <td>0.166619</td>\n",
       "      <td>0.468492</td>\n",
       "      <td>1.425995</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.844885</td>\n",
       "      <td>-1.205066</td>\n",
       "      <td>-0.528319</td>\n",
       "      <td>-0.012301</td>\n",
       "      <td>-0.181541</td>\n",
       "      <td>-0.852200</td>\n",
       "      <td>-0.365061</td>\n",
       "      <td>-0.190672</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.233880</td>\n",
       "      <td>2.016662</td>\n",
       "      <td>-0.693761</td>\n",
       "      <td>-0.012301</td>\n",
       "      <td>-0.181541</td>\n",
       "      <td>-1.332500</td>\n",
       "      <td>0.604397</td>\n",
       "      <td>-0.105584</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-0.844885</td>\n",
       "      <td>-1.073567</td>\n",
       "      <td>-0.528319</td>\n",
       "      <td>-0.695245</td>\n",
       "      <td>-0.540642</td>\n",
       "      <td>-0.633881</td>\n",
       "      <td>-0.920763</td>\n",
       "      <td>-1.041549</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-1.141852</td>\n",
       "      <td>0.504422</td>\n",
       "      <td>-2.679076</td>\n",
       "      <td>0.670643</td>\n",
       "      <td>0.316566</td>\n",
       "      <td>1.549303</td>\n",
       "      <td>5.484909</td>\n",
       "      <td>-0.020496</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   pregnants  Plasma_glucose_concentration  blood_pressure  \\\n",
       "0   0.639947                      0.866045       -0.031990   \n",
       "1  -0.844885                     -1.205066       -0.528319   \n",
       "2   1.233880                      2.016662       -0.693761   \n",
       "3  -0.844885                     -1.073567       -0.528319   \n",
       "4  -1.141852                      0.504422       -2.679076   \n",
       "\n",
       "   Triceps_skin_fold_thickness  serum_insulin       BMI  \\\n",
       "0                     0.670643      -0.181541  0.166619   \n",
       "1                    -0.012301      -0.181541 -0.852200   \n",
       "2                    -0.012301      -0.181541 -1.332500   \n",
       "3                    -0.695245      -0.540642 -0.633881   \n",
       "4                     0.670643       0.316566  1.549303   \n",
       "\n",
       "   Diabetes_pedigree_function       Age  Target  \n",
       "0                    0.468492  1.425995       1  \n",
       "1                   -0.365061 -0.190672       0  \n",
       "2                    0.604397 -0.105584       1  \n",
       "3                   -0.920763 -1.041549       0  \n",
       "4                    5.484909 -0.020496       1  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mydatapath=\"E:/myTrain_pima_indians_diabetes.csv\"\n",
    "mydata=pd.read_csv(mydatapath)\n",
    "mydata.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 三、准备数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train=mydata['Target']\n",
    "X_train=mydata.drop(['Target'],axis=1)\n",
    "\n",
    "#保存标签名称\n",
    "feat_names=X_train.columns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用默认参数的 Logistic Regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "lr=LogisticRegression()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#交叉验证\n",
    "#3折\n",
    "#StratifiedKFold分层抽样\n",
    "from sklearn.model_selection import cross_val_score"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### <font color=#0000FF >使用neg_log_loss评价指标进行模型评价</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "log_loss of each fold is: [0.4954799  0.50035386 0.44147359]\n",
      "cv log_loss is : 0.4791024465409764\n"
     ]
    }
   ],
   "source": [
    "#使用neg_log_loss评价指标进行模型评价\n",
    "loss=cross_val_score(lr,X_train,y_train,cv=3,scoring='neg_log_loss')\n",
    "print('log_loss of each fold is:',-loss)\n",
    "print('cv log_loss is :',-loss.mean())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### <font color=#0000FF >使用accuracy评价指标进行模型评价</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "log_loss of each fold is: [0.77042802 0.75       0.78823529]\n",
      "cv log_loss is : 0.7695544365606164\n"
     ]
    }
   ],
   "source": [
    "#使用accuracy评价指标进行模型评价\n",
    "loss=cross_val_score(lr,X_train,y_train,cv=3,scoring='accuracy')\n",
    "print('log_loss of each fold is:',loss)\n",
    "print('cv log_loss is :',loss.mean())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 用GridSearchCV实现正则化的 Logistic Regression及参数调优"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "logistic回归的需要调整超参数有：C（正则系数，一般在log域（取log后的值）均匀设置候选参数）和正则函数penalty（L2/L1） \n",
    "目标函数为：J =  C* sum(logloss(f(xi), yi)) +* penalty \n",
    "\n",
    "在sklearn框架下，不同学习器的参数调整步骤相同：\n",
    "1. 设置参数搜索范围\n",
    "2. 生成学习器实例（参数设置）\n",
    "3. 生成GridSearchCV的实例（参数设置）\n",
    "4. 调用GridSearchCV的fit方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color=#0000FF >使用log_loss指标评价模型</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "#为了比较GridSearchCV和LogisticRegressionCV，两者用相同的交叉验证数据分割\n",
    "from sklearn.model_selection import StratifiedKFold\n",
    "fold = StratifiedKFold(n_splits=3, shuffle=True, random_state=777)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=StratifiedKFold(n_splits=3, random_state=777, shuffle=True),\n",
       "       error_score='raise',\n",
       "       estimator=LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "          intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,\n",
       "          penalty='l2', random_state=None, solver='liblinear', tol=0.0001,\n",
       "          verbose=0, warm_start=False),\n",
       "       fit_params=None, iid=True, n_jobs=1,\n",
       "       param_grid={'penalty': ['l1', 'l2'], 'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000]},\n",
       "       pre_dispatch='2*n_jobs', refit=True, return_train_score=True,\n",
       "       scoring='neg_log_loss', verbose=0)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#导入相关包\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "#准备正则和超参数，一共2*7=14种搭配，每种搭配要进行三折交叉验证\n",
    "penaltys = ['l1','l2']\n",
    "Cs = [0.001, 0.01, 0.1, 1, 10, 100, 1000]\n",
    "tuned_parameters = dict(penalty = penaltys, C = Cs)\n",
    "#调用训练模型，评价指标是neg_log_loss\n",
    "lr_penalty= LogisticRegression(solver='liblinear')\n",
    "grid= GridSearchCV(lr_penalty, tuned_parameters,cv=fold, scoring='neg_log_loss',n_jobs = 1,return_train_score=True)\n",
    "grid.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.4773472783524872\n",
      "{'C': 1, 'penalty': 'l1'}\n",
      "[[ 0.40966448  1.12851286 -0.09299451  0.02476257 -0.08406819  0.62917452\n",
      "   0.27933807  0.14383969]]\n"
     ]
    }
   ],
   "source": [
    "# examine the best model of log loss\n",
    "#最佳得分\n",
    "print(-grid.best_score_)\n",
    "#最佳参数（包括正则项和超参数）\n",
    "print(grid.best_params_)\n",
    "#最佳参数下的回归系数\n",
    "print(grid.best_estimator_.coef_)\n",
    "test_means = grid.cv_results_[ 'mean_test_score' ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot CV误差曲线\n",
    "test_means = grid.cv_results_[ 'mean_test_score' ]\n",
    "test_stds = grid.cv_results_[ 'std_test_score' ]\n",
    "train_means = grid.cv_results_[ 'mean_train_score' ]\n",
    "train_stds = grid.cv_results_[ 'std_train_score' ]\n",
    "\n",
    "# plot results\n",
    "n_Cs = len(Cs)\n",
    "number_penaltys = len(penaltys)\n",
    "test_scores = np.array(test_means).reshape(n_Cs,number_penaltys)\n",
    "train_scores = np.array(train_means).reshape(n_Cs,number_penaltys)\n",
    "test_stds = np.array(test_stds).reshape(n_Cs,number_penaltys)\n",
    "train_stds = np.array(train_stds).reshape(n_Cs,number_penaltys)\n",
    "\n",
    "x_axis = np.log10(Cs)\n",
    "for i, value in enumerate(penaltys):\n",
    "    #plt.plot(np.log10(Cs), test_scores[:,i], label= 'penalty:'   + str(value))\n",
    "    plt.errorbar(x_axis, -test_scores[:,i], yerr=test_stds[:,i] ,label = penaltys[i] +' Test')\n",
    "    plt.errorbar(x_axis, -train_scores[:,i], yerr=train_stds[:,i] ,label = penaltys[i] +' Train')\n",
    "    \n",
    "plt.legend()\n",
    "plt.xlabel( 'log(C)' )                                                                                                      \n",
    "plt.ylabel( 'logloss' )\n",
    "#plt.savefig('LogisticGridSearchCV_C.png' )\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上图给出了L1正则和L2正则下、不同正则参数C对应的模型在训练集上测试集上的logloss。可以看出当C=1时性能最好（L1正则）(log1=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LogisticRegression(C=1, class_weight=None, dual=False, fit_intercept=True,\n",
      "          intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,\n",
      "          penalty='l1', random_state=None, solver='liblinear', tol=0.0001,\n",
      "          verbose=0, warm_start=False)\n"
     ]
    }
   ],
   "source": [
    "lr_best = grid.best_estimator_\n",
    "print(lr_best)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color=#0000FF >使用accuracy指标评价模型</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=StratifiedKFold(n_splits=3, random_state=777, shuffle=True),\n",
       "       error_score='raise',\n",
       "       estimator=LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "          intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,\n",
       "          penalty='l2', random_state=None, solver='liblinear', tol=0.0001,\n",
       "          verbose=0, warm_start=False),\n",
       "       fit_params=None, iid=True, n_jobs=1,\n",
       "       param_grid={'penalty': ['l1', 'l2'], 'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000]},\n",
       "       pre_dispatch='2*n_jobs', refit=True, return_train_score=True,\n",
       "       scoring='accuracy', verbose=0)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import StratifiedKFold\n",
    "fold = StratifiedKFold(n_splits=3, shuffle=True, random_state=777)\n",
    "#导入相关包\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "#准备正则和超参数，一共2*7=14种搭配，每种搭配要进行三折交叉验证\n",
    "penaltys = ['l1','l2']\n",
    "Cs = [0.001, 0.01, 0.1, 1, 10, 100, 1000]\n",
    "tuned_parameters = dict(penalty = penaltys, C = Cs)\n",
    "#调用训练模型，评价指标是accuracy\n",
    "lr_penalty= LogisticRegression(solver='liblinear')\n",
    "gridac= GridSearchCV(lr_penalty, tuned_parameters,cv=fold, scoring='accuracy',n_jobs = 1,\n",
    "                     return_train_score=True)\n",
    "gridac.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.765625\n",
      "{'C': 0.1, 'penalty': 'l1'}\n",
      "[[0.33103922 0.98375432 0.         0.         0.         0.50447359\n",
      "  0.1964853  0.08478112]]\n"
     ]
    }
   ],
   "source": [
    "# examine the best model of accuracy\n",
    "#最佳得分\n",
    "print(gridac.best_score_)\n",
    "#最佳参数（包括正则项和超参数）\n",
    "print(gridac.best_params_)\n",
    "#最佳参数下的回归系数w\n",
    "print(gridac.best_estimator_.coef_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "观察到L1正则将几个回归系数变成了0，容易得到稀疏解"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZQAAAEKCAYAAAA1qaOTAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3Xd4VGXax/HvnUkvhEBC6FV6l6ggSEdRabEgVmRlddeGdUXdRcCyIq+Kq7s2FNFFQUWkKVIUUVZEQFAEBURAeg8J6Zn7/WMmiBjIJJnJSbk/1zXXzJl5zpzfCZo7z3POeY6oKsYYY0xJBTkdwBhjTMVgBcUYY4xfWEExxhjjF1ZQjDHG+IUVFGOMMX5hBcUYY4xfWEExxhjjF1ZQjDHG+IUVFGOMMX4R7HSA0hQfH68NGzZ0OoYxxpQrq1evPqiqCYW1q1QFpWHDhqxatcrpGMYYU66IyHZf2tmQlzHGGL+wgmKMMcYvrKAYY4zxi0p1DMUYU3nl5OSwc+dOMjMznY5SZoWHh1O3bl1CQkKKtb4VFGNMpbBz505iYmJo2LAhIuJ0nDJHVTl06BA7d+6kUaNGxfoOG/IyxlQKmZmZVK9e3YrJaYgI1atXL1EPzgqKMabSsGJyZiX9+VhBMcaY07jq5a+46uWvnI5RblhB8cFVL37JDS987HQMY0w5Fx0dfeJ1//79qVq1KgMGDCiw7W233UaHDh1o1aoVERERdOjQgQ4dOvD+++8XaZtr1qxhwYIFJcrtKzso74P799xNONm48y4iyGU12BhTcvfffz/p6em8/PLLBX7+73//G4Bt27YxYMAA1q5dW6ztrFmzhvXr19O/f/9iZ/WV/Xb0weGgarQJ2saqOf92OooxpoLo06cPMTExxVp38+bNXHTRRXTq1Inu3buzadMmAKZPn06bNm1o3749vXr1IiMjg/HjxzNt2rRi9W6KynooPuj7j4/Y+OQFNF03gSMXXElcfE2nIxljSmDc3B/YsPtYoe027PG08eU4SqvaVXhkYOsSZ/PFzTffzOTJk2nSpAnLly/n9ttvZ+HChYwbN46lS5eSmJjI0aNHiYiIYMyYMaxfv55JkyYFPJf1UHwQ5HIRkfwc0ZrO5v/e7XQcY0wldvToUVasWMHll19Ohw4duO2229i9ezcAXbt25YYbbmDy5Mm43e5Sz2Y9FB81bHUOK+pcS+fdb7Lhq49p1eVipyMZY4rJ155Efs9kxi1dAhmnSFSV+Pj4Ao+pvPrqq3z99dfMmzeP9u3b891335VqNuuhFEH7a59gt9QgYtHfyM6y6RuMMaUvLi6OWrVqMWvWLADcbjfr1q0DYOvWrXTu3JlHH32UuLg4du3aRUxMDKmpqaWSzQpKEURExXDggkdp5N7B6umPOh3HGFOOXXDBBVx55ZUsWbKEunXr8sknn/i87vTp03nppZdo3749rVu3Zt68eQDcfffdtG3blrZt29K3b1/atGlD7969WbduHR07dgz4QXlR1YBuoCxJSkpSf9xg69uJA2iR9jWHh39BncYt/JDMGBNoGzdupGXLlkVapywOeQVaQT8nEVmtqkmFrWs9lGKoffVzuAni4Ht3oA4c+DLGlI4Zt3SpVMWkpKygFENi3SZ83/x22mes5NuFbzodxxhjygRHCoqIVBORRSKy2fscd5p29UVkoYhsFJENItLQ+76IyOMissn72Z2lmR8g6coH+NnVmLorxpGacri0N2+MMWWOUz2U0cASVW0KLPEuF+RNYKKqtgTOBfZ7378RqAe08H42PbBx/yg4JJS8S58lXo/ww7TTxTfGmMrDqYIyGJjqfT0VGHJqAxFpBQSr6iIAVU1T1XTvx38Fxquq2/vZ/lPXLw3Nzu7JNwnJnLPvXbas+9KJCMYYU2Y4VVASVXUPgPe5RgFtmgFHReQDEflWRCaKiMv7WRPgKhFZJSIfi0jTUsr9By2vm8hRicU9927ycnOdimGMCYQpl3oexicBKygislhE1hfwGOzjVwQDFwD3AecAjfEMdQGEAZne09heBV4/Q46bvYVn1YEDB4q9P6dTpWo825L+TrPcTXzz/tN+/35jTMVR2tPXz5o1i4kTJ5Y4t68CNvWKqvY93Wcisk9EaqnqHhGpxW/HRk62E/hWVbd61/kQ6Ay85v1sprfdLGDKGXK8ArwCnutQirMvhTn7kpv4/vu3ab3xWQ7suZqEWvUDsRljTAXir+nrc3NzCQ4u+Fd5cnKyf8L6yKkhrznAcO/r4cDsAtp8A8SJSIJ3uTewwfv6Q+8yQA9gU4By+kSCgoi78l+Eksv2t0c5GcUYU06UZPr6bt268fDDD9O9e3deeOEFZs+ezXnnnUfHjh258MIL2b/f8zf65MmTueuuuwC47rrrGDVqFOeffz6NGzc+MXWLPzk1OeSTwLsichOwA7gSQESSgL+o6khVzROR+4Al4rnR8Wo8w1v5608TkbuBNGBkqe/BKeqe1ZYVDf5E5x0v893nH9Cux2VORzLGnM7Ho2Hv94W32+udXNGX4yg128LFT5YsVxEcO3aMZcuWAXDkyBEGDRqEiPDSSy/x9NNPM2HChD+ss3//fpYvX87333/P0KFD/d6DcaSgqOohoE8B76/ipOLgPcOrXQHtjgJl7khZx2vG8uuEuVRb+iCZ51xIeGR04SsZY0wxDBs27MTrHTt2MHToUPbu3UtWVhbNmjUrcJ0hQ4YgIrRr145du3b5PZNNX+9HYeGRpPSZQJvF1/PV22PoMvIZpyMZYwria08iv2cyYn7gshRTVFTUide33XYbDz30EJdccgmLFy/myScL3r+wsLATrwMxj6NNveJnbboNYlWVfnT69Q22//St03GMMZVASkoKderUQVWZOnVq4SsEiBWUAGh07SQyJZzUmaNs8khjTIFKMn39qcaOHUtycjI9evQgMTHRjymLxqavD5CV7z/NuevH802Hf3LOkFtLZZvGmNMrzvT1ZXnIK1Bs+voyKCn5Ln4KbkGTtf/k6MF9TscxxhTHiPmVqpiUlBWUAAlyuQgZ8i+qaBo/vX2f03GMMSbgrKAEUOM257Gq1tWcd3gOG1cucjqOMcYElBWUAGt33RPsJZ6wBfeRk53ldBxjjAkYKygBFhldlb1dx9PYvY1VM55wOo4xxgSMFZRS0KHftayNPJ/2W15k93ZHpx0zxhTBiAUjGLFghNMxyg0rKKWk5rB/AbBv+p0BuULVGFP25U9fv3btWrp06ULr1q1p164dM2bM+ENbf0xfD7BmzRoWLFjgl/yFsalXSknN+k1Z0fRWOm95ljWLpnH2hdc5HckY45DIyEjefPNNmjZtyu7du+nUqRMXXXQRVatWPdHG1+nrC7NmzRrWr19P//79/ZL9TKyHUoqShj7IVldDav/vEdJSjzodxxjjkGbNmtG0qedGs7Vr16ZGjRoU5QaAmzdv5qKLLqJTp050796dTZs8Q+nTp0+nTZs2tG/fnl69epGRkcH48eOZNm1asXo3RWU9lFIUHBpGzsVPU3Pe5Xz139F0+etLTkcyplKasHICPx7+sdB2+W18OY7SoloLHjj3gSJnWblyJdnZ2TRp0sTndW6++WYmT55MkyZNWL58ObfffjsLFy5k3LhxLF26lMTERI4ePUpERARjxoxh/fr1TJo0qcjZisoKSilrntSXlf8bxDl7Z7Dlu+Gc1a6L05GMMQ7Zs2cP119/PVOnTiUoyLcBo6NHj7JixQouv/zyE+/l5uYC0LVrV2644QauvPJKLrus9O/JZAXFAc2ve4Zj/1pK7py7yGv9P1wul9ORjKlUfO1J5PdMpvQ/7V3Gi+3YsWNceumlPPbYY3Tu3Nnn9VSV+Pj4Ao+pvPrqq3z99dfMmzeP9u3b89133/kzcqHsGIoDYqslsPXsh2iR+yPfzHzW6TjGmFKWnZ1NcnLyid5EUcTFxVGrVq0Tt/B1u92sW7cOgK1bt9K5c2ceffRR4uLi2LVrFzExMaSmpvp9HwpiBcUhnQbcwg9h7Wm14RkO7N3hdBxjTCl69913WbZsGW+88caJ04GLchbX9OnTeemll2jfvj2tW7dm3rx5ANx99920bduWtm3b0rdvX9q0aUPv3r1Zt24dHTt2DPhBeZu+3kG/blpL4rQ+rIvtxTn3BPYf2pjKrjjT1wdyyKusKsn09XYMxUH1mnVgRf0b6fzrZL7/YjZtLxjsdCRjzEkqUyHxBxvycliHa8azS2pS9dPRZGYcdzqOMcYUmyMFRUSqicgiEdnsfY47Tbv6IrJQRDaKyAYRaeh9v4+IrBGRtSLypYicVZr5/Sk8IoojvSZQT3ez5u2xTscxxphic6qHMhpYoqpNgSXe5YK8CUxU1ZbAucB+7/svAteqagfgbeDvAc4bUG26D2F1lT502jGFHZsDe5rfVS9/xVUvfxXQbRhjKienCspgYKr39VRgyKkNRKQVEKyqiwBUNU1V070fK1DF+zoW2B3YuIHX4JpJZEkIKe/fibrdTscxxpgic6qgJKrqHgDvc40C2jQDjorIByLyrYhMFJH8KwBHAh+JyE7geuDJ021IRG4WkVUisqooc+WUtvia9fmx1V20zfqWVfNfdTqOMQbYfv0NbL/+BqdjlBsBKygislhE1hfw8PVUpmDgAuA+4BygMXCj97O7gUtUtS4wBXjmdF+iqq+oapKqJiUkJBR7f0pD0mX3sim4GY1WP0HK4YNOxzHG+FlpT18/a9YsJk6c6Lf8hQnYacOq2vd0n4nIPhGppap7RKQWvx0bOdlO4FtV3epd50Ogs4jMAdqr6tfedjOA0pnsP8CCgoMJHvQccTMv4Ztp99L5jqmFr2SMKXf8OX19bm4uwcEF/ypPTk72f/gzcGrIaw4w3Pt6ODC7gDbfAHEikt+t6A1sAI4AsSLSzPt+P2BjALOWqsbtzmdV4lDOPTibjas+dTqOMSYASjp9fbdu3Xj44Yfp3r07L7zwArNnz+a8886jY8eOXHjhhezf7/kbffLkydx1110AXHfddYwaNYrzzz+fxo0bn5i6xZ+curDxSeBdEbkJ2AFcCSAiScBfVHWkquaJyH3AEhERYDXwqqrmisifgZki4sZTYP7kzG4ERpvrJnDwmUWEfHwvOe2/JiQk1OlIxlQoe594gqyNhU9fn/mjp40vx1HCWrag5kMPFTlLcaavB8/kksuWLQPgyJEjDBo0CBHhpZde4umnn2bChAl/WGf//v0sX76c77//nqFDh/q9B+NIQVHVQ0CfAt5fheeAe/7yIqBdAe1mAf4vr2VEVJU4NnUZR8ev7uCrGf+ky3WPOB3JGBMAxZm+Pt+wYcNOvN6xYwdDhw5l7969ZGVl0axZswLXGTJkCCJCu3bt2LVrV4myF8SmXimjOvS7jnVr/0u7zf9m76/XUrNeub1205gyx9eeRH7PpMFbb/o9Q3Gnr88XFRV14vVtt93GQw89xCWXXMLixYt58smCT3wNCws78ToQ8zja1CtllAQFUWPY8wSh7HrnLqfjGGP8qCTT1xckJSWFOnXqoKpMnercyTxWUMqwWg2as67JX+iU/gVrFr3jdBxjjJ+UdPr6U40dO5bk5GR69OhBYmKiH5MWjU1fX8blZGex68kkwtwZVLl3NVExsSX6vvxpV2bcYrceNpVLcaavD+SQV1lVkunrrYdSxoWEhpHZ//+oxQHWvf2w03GMqVQavPVmpSomJWUFpRxoce5FfBN3Kefsfpuf1690Oo4xxhTICko50ey6Z0iTSLJnj8Kdl+d0HGPKpco0xF8cJf35WEEpJ2Kr1+TnDg/QMmcDK2c973QcY8qd8PBwDh06ZEXlNFSVQ4cOER4eXuzvsOtQypFOg25jw4YZtFg/kYMXXEl8Yh2nIxlTbtStW5edO3cWaYqTyiY8PJy6desWe30rKOWIBAURddnzRL7Th7Vv30P83X+codQYU7CQkBAaNWrkdIwKzYa8ypkGLTqypu71nJuygPVfznM6jjHGnGAFpRzqcO1j7JZEYpY8QFZWhtNxjDEGsIJSLoVHxnCwxxM00J2sfnuc03GMMQawglJutet5BWuie3D2tsn8+vMPPq835tD9jDl0fwCTGWMqKyso5Vj9a/5FLsEcfvdO1O12Oo4xppKzglKOxdduyIaWd9I+axWrPp7idBxjTCVnBaWc63TF39gcfBYNv3mUlKOHnI5jjKnErKCUc67gYGTAs1TXo2z479+cjmOMqcSsoFQAZ3Xozqoal3PugZn8uOZzp+MYYyopKygVRMtrn+KwVMU1/x5yc3KcjmOMqYQcKSgiUk1EFonIZu9zXAFteonI2pMemSIyxPtZIxH52rv+DBEJLf29KFtiqlZn53ljaJq3hZXvPeV0HGNMJeRUD2U0sERVmwJLvMu/o6qfqWoHVe0A9AbSgYXejycAz3rXPwLcVDqxy7YOF93I9+FJtPvpefbu/MXpOMaYSsapgjIYmOp9PRUYUkj7K4CPVTVdRARPgXm/COtXChIURPWhzxNMLjvfGeV0HGNMJeNUQUlU1T0A3ucahbQfBrzjfV0dOKqqud7lncBp53EXkZtFZJWIrKoM01bXbtyKdY3/TNLxz/l2ybtOxzHGVCIBKygislhE1hfwGFzE76kFtAU+yX+rgGanvWOOqr6iqkmqmpSQkFCUTZdbHa8aw46gutT48u+kH091Oo4xppIIWEFR1b6q2qaAx2xgn7dQ5BeM/Wf4qqHALFXNP3XpIFBVRPLv5VIX2B2o/SiPQsMjON5vInV0H99Oe9jpOMaYSsKpIa85wHDv6+HA7DO0vZrfhrtQz/07P8NzXMWX9Sulll0uYVXV/pyz679s3bDK6TjGmErAqYLyJNBPRDYD/bzLiEiSiEzObyQiDYF6wKlX6z0A3CMiW/AcU3mtFDKXO02ufZYMCSdj1ijceTZ5pDEmsBwpKKp6SFX7qGpT7/Nh7/urVHXkSe22qWodVXWfsv5WVT1XVc9S1StVNau096E8iEuozaZ299M6Zz0rZ//b6TjGmArOp4IiIjNF5FIRsSvry5mkIXfyY0grmn03gcMH9jgdxxhTgflaIF4ErgE2i8iTItIigJmMH0mQi4jk54jRdDZNu9fpOMaYCsyngqKqi1X1WuBsYBuwSET+JyIjRCQkkAFNyTVodS5ral9D56Pz2Z0T7XQcY0wF5fMQlohUB24ERgLfAs/hKTCLApLM+FW7a59gjyTQJG8bue6CLuUxxpiS8fUYygfAF0AkMFBVB6nqDFW9A7A/ecuBiOgqHLjgMRoH7WFPTqTTcYwxFZCvPZQXVLWVqv4zf8qUfKqaFIBcJgDa9R7GGndTuvAdu/fataDGGP/ytaC0FJGq+QsiEicitwYokwmgnJBooslgw/RHnI5ijKlgfC0of1bVo/kLqnoE+HNgIplAinblspZmXHDkA1avXed0HGNMBeJrQQnyThsPgIi4gEp/U6vyKjQkGCSIw/MfIceuoDfG+ImvBeUT4F0R6SMivfHMrbUgcLFMIAUFBbG7+Q30yV7K/IULC1/BGGN84GtBeQD4FPgrcBueuyz+LVChTOA1HPx30l3RxK94ggOpNnONMabkfL2w0a2qL6rqFap6uaq+rKp5gQ5nAkci48jsfBfdZB0fvD/N6TjGmArA1+tQmorI+yKyQUS25j8CHc4EVnyv20kJrcn5vzzHt9sPOR3HGFPO+TrkNQXPfF65QC/gTeCtQIUypSQknLALx9A2aBtL3n8Rt/u0N740xphC+VpQIlR1CSCqul1VxwK9AxfLlJbws68mpUpzhqa8wftf/+x0HGNMOeZrQcn0Tl2/WURuF5FkoEYAc5nSEhRElYFPUD/oANsXvkBKek7h6xhjTAF8LSh34ZnH606gE3Adv93C15RzclYf0up05Sb3e/x7wWqn4xhjyqlCC4r3IsahqpqmqjtVdYT3TK8VpZDPlAYRoi99nGqSRuya/7BxzzGnExljyqFCC4r39OBOJ18pbyqg2h3JbnkZfwr+mEmzPkfVDtAbY4rG1yGvb4HZInK9iFyW/whkMFP6Qi98hFBx03P3a8xZZ7MRG2OKxteCUg04hOfMroHex4DiblREqonIIhHZ7H2OK6BNLxFZe9IjU0SGeD+bJiI/ich6EXnd7hrpJ3ENkXNHMjT4c96Zv5DjWblOJzLGlCO+Xik/ooDHn0qw3dHAElVtimcal9EFbPMzVe2gqh3wFLJ0IH/iqWlAC6AtEIHnLpLGD4K6/w1Corgp8y1e+GyL03GMMeVIsC+NRGQK8IdB9RIUlcFAT+/rqcBSPPOFnc4VwMeqmu7d7kcnZVsJ1C1mDnOqqOq4LriLfp8+ymtffsTWTnVpnGA35TTGFM7XIa95wHzvYwlQBUgrwXYT8+/86H0u7JqWYXhmOP4d71DX9djMx/7V+Vbyomsy2vUO4+f+YAfojTE+8amHoqozT14WkXeAxWdaR0QWAzUL+Ohhn9N5vqcWnqGtTwr4+D/AMlX94gzr3wzcDFC/fv2ibLryCo3E1eshOsy9k7AtH7NkY0P6tkp0OpUxpozztYdyqqbAGX87q2pfVW1TwGM2sM9bKPILxv4zfNVQYJaq/u4SbhF5BEgA7ikkxyuqmqSqSQkJCT7smgGgw7VofHMeDn+Xx+d+T2aOTS5tjDkzX2cbThWRY/kPYC5nPuZRmDn8dqX9cGD2GdpezSnDXSIyErgIuFpV7ZaDRTC++kTGV59YeENXMNJ3LPXdu+hy7CNeXWaTSxtjzszXs7xiVLXKSY9mpw6DFdGTQD8R2Qz08y4jIkkiMjm/kYg0BOoBn5+y/ktAIvCV95TiMSXIYk6n+cVQvwsPhM/i9aXr2XU0w+lExpgyzNceSrKIxJ60XDX/mpDiUNVDqtpHVZt6nw9731+lqiNPardNVeuc2gtR1WBVbZJ/WrGqji9uFnMGItBvPLF5h7lR5vPE/I1OJzLGlGG+HkN5RFVT8hdU9SjwSGAimTKl3rnQciB/DZnPiu9/ZPmWg04nMsaUUb4WlILa+XSGWEUwYsEIRiwY4XQM5/R5hBB3Fg9Fz2XsnB/IybPDVsaYP/K1oKwSkWdEpImINBaRZwGb57yyiG+KdBpOct5Csg9s4c2vtjudyBhTBvlaUO4AsoEZwLtABnBboEKZMqjHaCQ4jKfiZjNp0SYOpGY5ncgYU8b4epbXcVUdnX89h6o+pKrHAx3OlCExicj5t3Ne+uc0zdvEhAU/Op3IGFPG+HqW1yIRqXrScpyIFHTluqnIzr8DohJ4Nu4D3l/9K2t2HHE6kTGmDPF1yCvee2YXAKp6BLunfOUTFgM9HqBB6hqGRP3AI7N/IM9t83wZYzx8LShuETkx1Yr3gsNK85tk2PM/MOz5H5yOUTZ0uhGqNWZc5Hv8sOsI76761elExpgywteC8jDwpYi8JSJv4bly/cHAxTJllisE+owhNnUz99ZYw8RPfiIlPafw9YwxFZ6vB+UXAEnAT3jO9LoXz5lepjJqNQTqdOLmvHfISE/jmUU/OZ3IGFMG+HpQfiSe+6Dc6328BYwNXCxTpnmnZAk5vodJDVfy1ortbNh9zOlUxhiH+TrkNQo4B9iuqr2AjsCBgKUyZV/DbtD0Ivodnka98EzGzrEbcRlT2flaUDJVNRNARMJU9UegeeBimXKh71iCslN5qeHnrNx2mDnrdjudyBjjIF8Lyk7vdSgfAotEZDZgvz0qu8RW0P4aWux4h141M3nio40cz8p1OpUxxiG+HpRPVtWjqjoW+AfwGlDs6etNBdLrQUSC+L/q89h3LIvnP93idCJjjEOKfAtgVf1cVeeoanYgAplyJrYunHcL1X+exe2tMnnty61sPZDmdCpjjAOKe095Y37T7W4Ij+UO91uEBbsYN3eDHaA3phKygmJKLiIOut9H2LbPeOrsw3y+6QCLN+53OpUxppRZQalkZtzShRm3dPH/F5/zZ4itx8V7XqRpQiSPzttAZk6e/7djjCmzrKAY/wgJh95/R/au44V2v7DjcDqvLtvqdCpjTClypKCISDXvlPibvc9xBbTpJSJrT3pkisiQU9o8LyJ2BLisaDsUEtvS/IdJDGxdjX8v3cLOI+lOpzLGlBKneiijgSWq2hTPlC6jT22gqp+pagdV7QD0BtKBhfmfi0gSUPXU9YyDgoKg31g4up1H66wE4ImPNjqbyRhTapwqKIOBqd7XUyn8mpYrgI9VNR1ARFzAROBvAUtYQY1YMIIRC0YEbgNN+kCjHlT9ZhJ3davJR9/vZfmWg4HbnjGmzHCqoCSq6h4A73NhN+saBrxz0vLtwJz87zBliAj0GwcZhxkpc6hXLYKxc34gJ8/tdDJjTIAFrKCIyGIRWV/AY3ARv6cW0Bb4xLtcG7gSeN7H9W8WkVUisurAAZvPslTU7ghtriB45Ys83rs6m/enMfV/25xOZYwJsIAVFFXtq6ptCnjMBvZ5C0V+wTjTRQtDgVmqmn8Xp47AWcAWEdkGRIrIaef7UNVXVDVJVZMSEhL8sm/GB33+Ae5cLtg1mR7NEnhu8WYOpGY5ncoYE0BODXnNAYZ7Xw8HZp+h7dWcNNylqvNVtaaqNlTVhkC6qp4VsKSmeOIawjkjkbX/5bGuwWTm5jFhwY9OpzLGBJBTBeVJoJ+IbAb6eZcRkSQRmZzfyHvv+np4bjnsmMjUHKKO5dh0IkXV/X4Ijabemonc1K0x76/eyertR5xOZYwJEEcKiqoeUtU+qtrU+3zY+/4qVR15UrttqlpHVU97RFdVowOdNyoth+oHMtkx/EayttrFej6Lqg5dR8FPHzGq6UESq4Qxds4P5LmtMBtTEdmV8j44UDOCQwlhZP74I1sHD+HAv/6FO8uOB/ik860QU4uIpWN56OIWfL8rhXdX/ep0KmNMAFhB8YUIx6uE0uSj+VTp35+D/3mRrYMGkbZ8udPJyr7QSOj5IOz8hkFhqzm3YTWeWvAjR9Pt7gfGVDRWUIogOD6eOhOfov7rryEIv940kl333keunY58Zh2uhfjmyJLxjB3QjJSMHJ5ZtMnpVMYYP7OCUgxR559Pozmzib/1VlIXLuTnSy7lyPTpqNsu3iuQKxj6joWZQWgxAAAc4klEQVRDW2i150Ou69yA/67Yzobdx5xOZozxIysoPnDLHw8iB4WFkXDnHTSaPZvwVq3YO3Yc26++hswf7dTYAjW/GOp3gaVPck+P2sRGhDB2zg925pwxFYgVFB/MPDuHV7pn8emOT8l15/7us7DGjaj/xhRqT3iS7F9/5ZfLr2DfhKdwHz/uUNoySgT6jYfj+6m69lX+1r8FK7cdZs663U4nM8b4iRUUHySkCvuqKKM+G8XFH1zMK9+9wsGM3yY8FBFiBw+myUfzqXrZZRyeMoWfBwwk9dNPHUxdBtU7F1oOhP/9i6Etw2lbJ5YnPtrI8azcwtc1xpR5VlB80HNTCA/ND2NSr0k0qtKI5799nn7v9eP+z+9n1d5VJ4ZtXFWrUuvR8TR4exqu6Gh23nobv95+Ozl7bA7LE/o8AjkZuJY9xbjBrdl3LIvnPz3tzDnGmHLECoqPXCr0qd+HVy58hXnJ87im5TUs372cEZ+M4LI5lzH9x+mkZXvu9RV59tk0+mAmCffew/Evl/PzpQM4NOUNNNf+Eie+KXQaDquncHbUYa7oVJfXvtzKzwfsPmnGlHdWUIqhQZUG3H/O/Sy5cgnjzx9PqCuUx79+nD7v9eGxFY+x6cgmJCSE+D//mcbz5hJ5ThL7J0zglyuHkvHdd07Hd16P0eAKgyXjeaB/C8KDXYyfu8EO0BtTzllBKYGI4AiSmyYzY8AM3rn0Hfo16MeHWz7k8jmXM/zj4Xy09SOkViL1XnqJOs89R96hQ2y7ahh7x48nLzXV6fjOiUmE82+HDR+SkLKeUX2b8vmmAyzeeKZJp40xZZ0VFD9pE9+Gx7o9xuIrFnNf0n0cyDjAA188QN/3+/L8t89zvGtbGn80n7jrruPI9Bn8fMklpMyfX3n/Kj//DohKgEVjGN6lAU1rRDN+3g9k5uQ5nazUBfwumqXovCmXc96Uy52OYRxiBcXPqoZXZXjr4cxLnsdLfV+iXUI7Xlv/Gv0/6M9dKx/k5xt70ODd6YTUSGT3vffx68g/k71jh9OxS19YDPR4ALZ/ScjWxYwd1JpfD2fwyjKbfNOUDRWlOJbmflhBCZAgCaJrna483/t5Fly2gJva3MR3B77jL4v/whWbHuDzMZdQ5YF7yFi7lq0DB3HwpZfQ7Eo2v1WnG6FaY1g8lq6N47ikbU3+s3QLO4+kO53MGFMMVlBKQa3oWtx59p0svmIxT3V/ioSIBJ5e+yyDgl/ivbHdyevSkQOTnmNr8mUcX7nS6bilxxUCfcbA/g2wbjoPX9oKgMfnb3Q4mDGmOKyglKIQVwgXN7qYqRdPZeagmSQ3TWbuseUM67KKaTc1JC31MDtuGM7uBx8i90gluRFVqyFQpxN89jh1ouC2nmfx8fq9LN9y8IyrVaTjDsZUFFZQHNIsrhl/7/x3Ph36KX8/7+/80CycP91wjPldwzky50M29+/P0ZkfVPyD9vlTshzbBV+/zJ+7N6Z+tUgemfMDOXk22aYx5YkVFIdFhURxVYur+GDQB7wycCr7b+jH6D+F8GPMMfY8/DDrhg7i+KafnI4ZWA27QdOL4MtnCM9J4R8DWrFlfxpT/7fN6WTGmCKwglJGiAidEjvxVI+nmHLrEg783128MySOnM1b2Jo8hAUP3sD+wzudjhk4fcdCVip88TR9W9agZ/MEJi3ezP7UTKeTGWN8ZAWlDIqPiOfmDrcw5ollHH/zSTZ1SqTBrG/YcMmFPPuf4Xyz95uKNxSW2AraXwMrX0FSfmXMgFZk5eYx4eMK3jszpgKxglKGBQcF07PdYC5/cylh/5lAVEQV+v9rJev+Opwb3hrI2xvfJjW7Al1x3+tBkCD49HEaJ0RzU7fGzFyzk9XbK8kJCsaUc44UFBGpJiKLRGSz9zmugDa9RGTtSY9MERni/UxE5HER2SQiG0XkzkDmnX5Ha6bf0TqQmyhU496D6PTJMqre/le6bHFxzzO/sObFx+k7ozfjvxrPT4crwF/ysXXhvFvguxmw93vu6H0WiVXCeGTOevLcFaxHdpINe46xYY/dvdKUf071UEYDS1S1KbDEu/w7qvqZqnZQ1Q5AbyAdWOj9+EagHtBCVVsC00sltcOCQkOpdfudNJ07l+pnn8dNC93839shrFs+iyvmXsENH9/A/K3zyc4rxxdIdrsbwmNh0SNEhQXz0CUtWb/rGDO++dXpZMaYQjhVUAYDU72vpwJDCml/BfCxquZfQv1XYLyqugFUtVLNKhjasCH1XnuN2hMnkngsiMdez+Zf33ck7egBRn8xmn7v92PS6knsStvldNSii4iD7vfBz0tg61IGta/NuY2qMfGTHzmaXo4LpTGVQLBD201U1T0AqrpHRGoU0n4Y8MxJy02Aq0QkGTgA3KmqmwtaUURuBm4GqF+/fomDlxUiQuzAAUR3v4D9zz4LM95lwqpEjt56C/+N38yUH6bw+vrX6V63O1c1v4qudboSJM4dMlNVctw5ZORmkJmbSVZeFhm5GWTlZZGZm0lmXuZvz1WrkVmjHpmf3k9mx+tp3OwY32Vs45oPP6RF7XAyczNZs/cHQLn2o2sd2yd/yRTPXG7lbl8UsvPcZOW4yczNIyvHTVrOMVAX508ZRnBQGCFBoYQGhRMWFEZocBjhrgjCg8OICI4gKjiC8JAwokMiiQqNIDosgiqhkZ7nsEiqhkdRJSyS2PBIQoOd+lVliiJg/0oishioWcBHDxfxe2oBbYFPTno7DMhU1SQRuQx4HbigoPVV9RXgFYCkpKQKNxDvio2l1tixVB0yhD2PjCV6zL+5r3dv/nbPVD5I/YKZm2by+c7PqRtdl6HNhzLw5fVEZQv096yf6849/S/307zOb3fyOhl5GWTlZv2+MJxUODJzM1GK8OOPEiCToPWTCQ+OILpaMNuPu3AfjCU2PNLbKIjokGh//0gd4Cn0ZXVfcvPcpGfnkZGTd+I5I9vzcJ90tqErSFAiICiXbE0nI/cobrJRyUbJRiUHCSreTebUHYxoCEIooiEEEYpLwnBJCCESRrCEERoURqgrnNCgMMKDwwhzRRARHE5ESDgRweFEhUQSHRpOVEgE0WGRxIRGUiU8gtiwKM9zeBQxoeEEBdm5SsUlTpx+KiI/AT29vZNawFJVbX6atqOA1qp680nv/Qj0V9VtIiLAUVWNLWy7SUlJumrVqiLnzZ/iY0r/KUVetzRpTg6H33yLAy+8AEDC7bcTc+0wPt2zjOk/TWf1vtW48iAqG7RKDBl5GeS6i/c/eLgrnLDgMMJd4UQERxDmCiM8OJxwV7jnOTicMJfnL9H8tgW2O91zUCjhUy4hOOsYcvsqUrKD6PX0Us5KiGbGLZ3p/MYVAHw9Yqbffn5OyZ8J1sl9ycrNY8ehdH4+cJxfDh5n64E0z/PB4xw+/ttQoytIaFAtkkbxUTROiKJRfDSNE6JoHB9FQkxYof8uObm5HMvOICUznZTMdI5lHedYZjpp2RknHsdzMkjPySA9N5OMnIwTf6Bk5WWRnZdJtjuLHHcWOZpNrjuLPLJxaxZuycZNDirZIDmIFH2mBVUBDUY0FLfbBQgucRXrZ1pW5KnnlhCvXfganesX+Gu2UCKyWlWTCmvnVD9yDjAceNL7PPsMba8GHjzlvQ/xHKh/HegBbApAxnJHQkKoftOfqHJxf/Y+9jj7J04kZc4ceowbS//+b7D5yGaemziUzGCl6dmDT/xyP11BKOiXfVhwGGGusNIZPus3Dv57Oax6ndjOf+X+i5rz4AffM2fd7sBvuwJyu5W9xzJPFIytB4+z1VtAdh5J5+QT6RJiwmgcH8VFrRNpHB99ooDUqxZJiKv4//YhwcFUD46hemSMH/bozNJzsjiacZxjWemkZGRwLOs4qdkZpGalk5adTnpOprd4ZZKek0FGbiZZeZ7ilZ2Xxc9HtoEoNWMKGmgpP3al7gUgJiyykJYl51RBeRJ4V0RuAnYAVwKISBLwF1Ud6V1uiOdsrs8LWH+aiNwNpAEjSyd2+RBSuzb1/vNvUhcvZu9jj7Pt6muoetVQGt99NwPXhQBw0fgHHE7pgyZ9oFEP+Pwp6HANQ5Pq8c7KHTw+fyNaM5igYg6fVHTHMnO8hSKNrQeOnygc2w4eJ+OkG5hFhrpoFB9F+3pVGdKxDk0SomgU73nEhIc4uAf+ERkSRmRIGLWpVqz1PT1HYeF1L/o3WCnL7wG3TqwX8G05UlBU9RDQp4D3V3FScVDVbUCdAtodBS4NYMQKIaZvXyI7d+Hg889z+K23SF20mEhXDunR5eQAp4inl/JKT1j+HK4+Yxg3qDXJ//kfkSEdiEko+vBlRZGd62bH4fTfhqbyh6oOpnEw7bchqiCBetUiaRwfRZfG1U8MTzVOiCaxShieEWNj/KOc/GYxxeWKjiLxwdHEDh7EnrHjiP/uO7KPBHHotdeJHTSQ4IQEpyOeWe2O0OYK+Oo/cM5IOtavzRWd6jJzdS5NIpc4nS6gVJV9x7LY6u1pnHxs49cjGb+72DM+OpRG8VH0aZFIoxNFI4r61aIIDbaDzKZ0WEGpJMJbtaLhO2+zvGcS0cey2T9xIvufeYbobt2Ivewyonv1JCg01OmYBevzD9gwG5b+EwY9zwP9WzBrzRa2HxrA1gNpTqcrsdzsKqg7hNlrd/3hoHh69m9DVOEhQTSKj6Z17VgGtq/tPa7hOb4RG1H+h6hM+WcFpRIRl4vjVUI4XiWEns9PJ2XWh6TMnk3aqFG4YmOpMmAAscnJhLduVbaGQuIawjkjYeXL0Pk2Emq0oE61Jew4dCm9nz718Fp55DkzatT2tYhA3bgIGsdHc07Dat7jGp4zqWpWCScoqAz9uxhzCisolVRY48bUuPceEu4axfH/fUXKrA84+t57HJk2jbBmzYhNTiZ24ACC4+OdjurR/X5YOw2WjIOr3yGxyleEhxzgtp6TnE5WYv/4fBIiubx31XjqV4skPKR8n6ZqKi8rKJWcuFxEX9CN6Au6kZeSwrGPP+borFnsnzCB/f/3f0R3707sZcnE9OiBODkkFlUduo6CTx+F7V8holSN3MzgDn84Z6PceeLbrQA0Swz8qbTGBJIVFHOCKzaWuGHDiBs2jKwtW0j58ENSZs8h7bPPcFWtSpWBA6maPITwVq2cCdj5VvhmMiz6B48ciPKcBWaMKTPs9I9Kxtep+MPOOosa993HWZ99Sr1XXiayc2eOTp/OL5ddztYhyRyeOpXcQ4dKIfFJQiOh54Ow8xti1KZ7N6assYJizkiCg4nu3p26k56l6RfLSBzzDyQkhH3/fJLNPXry6223k7p4MZqTUzqBOlwL8c1JzN0LFe2ulcaUczbkZXzmqlqVatdcQ7VrriFr82aOzvqQlDlzSFuyBFe1asQO9J4l1qJFAEMEQ9+xhE2/mjj34cBtxxhTZFZQTLGENW1K4t/up8Y9d5P25ZekzPqQw2+/w+GpbxLWsiVVk5OpMnAAwXF/uBlnyTW/mOMSSULefti8COqdB+FV/L+dUtIw+z6nI/hNRZis0xSfFRQflPVZhp0kwcHE9OxJTM+e5B45wrH5H5Eyaxb7nniCfRMnEtOzB7HJyURfcAES4qeL70TY66pFw9xfYNoVnvvQ12wHDbpCw65QvwtEFm/+JmNM8VlBMX4THBdHteuupdp115L50yZSZs0iZe5cUhctxlW9OrEDB3qGxJo3K/G2mtSpBe4a0Gs0bP8fbFvuOQNsxb89DWq0hgbnewpMg64QXdg93IwxJWUFxQREePNmhI9+gBr33kPaF1+SMmsWh6dN4/AbbxDeqhWxyclUGXBpyYbEglzQuKfnAZCbBbtWw/blngKz9m345lXPZ9Wb/lZcGnSF2PJ//YoJrIoyfFea+2EFxQSUhIQQ07sXMb17eYbE5s7j6Iez2Pf44+x76ilievUiNnmIZ0ispLd5DQ7z9EoanO+5sj4vB/asg21fenox6z+A1W942lZtAA27edt39UzvYte1GFMiVlBMqQmOi6PaDddT7YbryfzxR89cYnPnkrpwIa74eGIHDaJq8hDCmjb1zwZdIVA3yfPodhe482Dfek/vZfty+Oljz3QuADG1vT2Y86FBN4hvWmoFZsYtXUplO8YEmhUU44jwFi0If3C0d0jsC47OmsXhN9/k8OuvE96mDbHJQ4i99FJcVav6b6NBLqjV3vPociu43XDwJ28PZjn8sgy+f8/TNirht+LS4Hyo0QrsXuPGnJEj95R3SnHvKV+RjFgwAiibZ67lHj7MsblzOfrBLLJ++gkJCSG6Tx+qJg8hqmvX3w2Jbe/XEYAGi771XwBVOPSzp7jkH4c5ttPzWXjV34bHGpzvOavM5ae/x6Z47xU3Yr5/vs8YPyvr95Q35g+Cq1Wj2vDhVBs+nMyNGzk6axbH5s4jdcECghMSiB08iNghQwg766zABBCB+LM8j07DPe8d2f77AvPTR573Q2Og/nneU5W7Qa0OEFy8yTO3v70bgAYj/LETzgpIoXdIRdmX0twPKyimTApv2ZKaLVuSeN99pH7+OSmzPuTQlDc4NPk1wtu1Iy8tl+DIUpjmPa6B59HhGs/ysd2eA/z5BWbLOM/7wRFQ79zfroWpkwQh4YHPZ0wZYgXFlGkSGkqVfv2o0q8fuQcPkjJ3HikffEDOkVxyjuTy03mdcUVHExQdTVBMNK6oaIJiYgiKjsIVE0NQlPf9aO/7UdG4YvLbx+CKiiratPxVakPbKzwPgLQDsON/v10Ls/SfgIIr1FNU8q+FqXsuhEUH5GdkTFnhSEERkWrADKAhsA0YqqpHTmnTC3j2pLdaAMNU9UMR6QNMxDO5ZRpwo6puKYXoxkHB8fFUH3Ej1W4czraeHcjNyCPm0ktxH08jLzUNd1oaOQf24/7lF9ypqeSlpYEPk1ZKaOhvRSg6pujFqW4vgpoPQFwuyDgCO1b8dqryl8/CF/8HQcGeYbH8a2Hqd4bw2FL4qRlTepzqoYwGlqjqkyIy2rv8wMkNVPUzoAOcKEBbgIXej18EBqvqRhG5Ffg7cGMpZTcOExGC6rcnFKg55h9nbOvOysKdluYtMMc9r9M8xcadmuYtRqm404572hz3vJ+z41cy07zvp6V5zggrRFBk5Imej6c4NSEoshVBkoEr5zBB2/YS9NkUXMGvEBQCQTUa4GrQgZDI4+RlhpCzaY2ffkLOkSBPAbd9KTvy90Mz05HwyIBuy6mCMhjo6X09FVjKKQXlFFcAH6tqundZgfzZAGOB3f6PaCqCoLAwgsLCoHr1Yn+HqqLp6d6ClIo77bce0e+KU1oaeWknFae0VHL27sWd6lnHnZ4OnDzsdQxYBrgAN1sGXVuynS1DbF/Knuz1KwhL6h3QbThVUBJVdQ+Aqu4RkcImWhoGPHPS8kjgIxHJwPN/ZefAxDRlVYO33iy1bYkIEhVFUFQUJBZ/TjDNy8N9/PhJvaVU3ClHOPz4HQQF5xJ94SA/pnZG2sI5ALYvZUj+fgTX99MFw2cQsIIiIouBmgV89HARv6cW0Bb45KS37wYuUdWvReR+PMVm5GnWvxm4GaB+/fpF2bQxfiUuF64qVXBVqcLJ8y4f+mc4eW6oeu/TjmXzl5QFnwK2L2VJ/n64atQL+LYCVlBUte/pPhORfSJSy9s7qQXsP8NXDQVmqWqOd90EoL2qfu39fAaw4Aw5XgFeAc+FjUXcDWOMMT5yai6JOYD3yjGGA7PP0PZq4J2Tlo8AsSKSPwd6P2Cj3xMaY4wpEqeOoTwJvCsiNwE7gCsBRCQJ+IuqjvQuNwTqAZ/nr6iquSLyZ2CmiLjxFJg/lWp6Y4wxf+BIQVHVQ0CfAt5fxUnHQlR1G/CHG1eo6ixgVgAjGlNqGlxT2+kIflPepyk5WUXZl9LcD7tS3hin2aSQpoKw+biNMcb4hfVQKpmyOG29MaZisB6KMcYYv7CCYowxxi+soBhjjPELKyjGGGP8wgqKMcYYv7CCYowxxi+soBhjjPELKyjGGGP8wgqKMcYYvxDVynOLEBE5AGwv5urxwEE/xnFSRdmXirIfYPtSVlWUfSnpfjRQ1YTCGlWqglISIrJKVZOczuEPFWVfKsp+gO1LWVVR9qW09sOGvIwxxviFFRRjjDF+YQXFd684HcCPKsq+VJT9ANuXsqqi7Eup7IcdQzHGGOMX1kMxxhjjF1ZQikBEHhWR70RkrYgsFJFyezNwEZkoIj9692eWiFR1OlNxiMiVIvKDiLhFpFyejSMi/UXkJxHZIiKjnc5TXCLyuojsF5H1TmcpCRGpJyKfichG739bo5zOVFwiEi4iK0VknXdfxgV0ezbk5TsRqaKqx7yv7wRaqepfHI5VLCJyIfCpquaKyAQAVX3A4VhFJiItATfwMnCfqq5yOFKRiIgL2AT0A3YC3wBXq+oGR4MVg4h0B9KAN1W1jdN5iktEagG1VHWNiMQAq4Eh5fTfRIAoVU0TkRDgS2CUqq4IxPash1IE+cXEKwoot9VYVReqaq53cQVQ18k8xaWqG1X1J6dzlMC5wBZV3aqq2cB0YLDDmYpFVZcBh53OUVKqukdV13hfpwIbgTrOpioe9UjzLoZ4HwH7vWUFpYhE5HER+RW4FhjjdB4/+RPwsdMhKqk6wK8nLe+knP7yqohEpCHQEfja2STFJyIuEVkL7AcWqWrA9sUKyilEZLGIrC/gMRhAVR9W1XrANOB2Z9OeWWH74m3zMJCLZ3/KJF/2oxyTAt4rtz3fikREooGZwF2njE6UK6qap6od8IxCnCsiARuODA7UF5dXqtrXx6ZvA/OBRwIYp0QK2xcRGQ4MAPpoGT6YVoR/k/JoJ1DvpOW6wG6Hshgv7/GGmcA0Vf3A6Tz+oKpHRWQp0B8IyIkT1kMpAhFpetLiIOBHp7KUlIj0Bx4ABqlqutN5KrFvgKYi0khEQoFhwByHM1Vq3gPZrwEbVfUZp/OUhIgk5J/BKSIRQF8C+HvLzvIqAhGZCTTHc1bRduAvqrrL2VTFIyJbgDDgkPetFeXxjDURSQaeBxKAo8BaVb3I2VRFIyKXAJMAF/C6qj7ucKRiEZF3gJ54ZrbdBzyiqq85GqoYRKQb8AXwPZ7/1wEeUtWPnEtVPCLSDpiK57+tIOBdVR0fsO1ZQTHGGOMPNuRljDHGL6ygGGOM8QsrKMYYY/zCCooxxhi/sIJijDHGL6ygGONHIpJWeKszrv++iDT2vo4WkZdF5GfvTLHLROQ8EQn1vrYLk02ZYgXFmDJCRFoDLlXd6n1rMp7JFpuqamvgRiDeO4nkEuAqR4IacxpWUIwJAPGY6J1z7HsRucr7fpCI/Mfb45gnIh+JyBXe1a4FZnvbNQHOA/6uqm4A74zE871tP/S2N6bMsC6zMYFxGdABaI/nyvFvRGQZ0BVoCLQFauCZGv117zpdgXe8r1vjueo/7zTfvx44JyDJjSkm66EYExjdgHe8M73uAz7HUwC6Ae+pqltV9wKfnbROLeCAL1/uLTTZ3htAGVMmWEExJjAKmpb+TO8DZADh3tc/AO1F5Ez/j4YBmcXIZkxAWEExJjCWAVd5b26UAHQHVuK5Bevl3mMpiXgmU8y3ETgLQFV/BlYB47yz3yIiTfPvASMi1YEDqppTWjtkTGGsoBgTGLOA74B1wKfA37xDXDPx3ANlPfAynjsBpnjXmc/vC8xIoCawRUS+B17lt3ul9ALK3ey3pmKz2YaNKWUiEq2qad5exkqgq6ru9d6v4jPv8ukOxud/xwfAg6r6UylENsYndpaXMaVvnvemR6HAo96eC6qaISKP4Lmn/I7Trey9EdeHVkxMWWM9FGOMMX5hx1CMMcb4hRUUY4wxfmEFxRhjjF9YQTHGGOMXVlCMMcb4hRUUY4wxfvH/q9kDVYMtwm4AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot CV误差曲线\n",
    "test_means = gridac.cv_results_[ 'mean_test_score' ]\n",
    "test_stds = gridac.cv_results_[ 'std_test_score' ]\n",
    "train_means = gridac.cv_results_[ 'mean_train_score' ]\n",
    "train_stds = gridac.cv_results_[ 'std_train_score' ]\n",
    "\n",
    "# plot results\n",
    "n_Cs = len(Cs)\n",
    "number_penaltys = len(penaltys)\n",
    "test_scores = np.array(test_means).reshape(n_Cs,number_penaltys)\n",
    "train_scores = np.array(train_means).reshape(n_Cs,number_penaltys)\n",
    "test_stds = np.array(test_stds).reshape(n_Cs,number_penaltys)\n",
    "train_stds = np.array(train_stds).reshape(n_Cs,number_penaltys)\n",
    "\n",
    "x_axis = np.log10(Cs)\n",
    "for i, value in enumerate(penaltys):\n",
    "    #plt.plot(np.log10(Cs), test_scores[:,i], label= 'penalty:'   + str(value))\n",
    "    plt.errorbar(x_axis,-test_scores[:,i], yerr=test_stds[:,i] ,label = penaltys[i] +' Test')\n",
    "    plt.errorbar(x_axis,-train_scores[:,i], yerr=train_stds[:,i] ,label = penaltys[i] +' Train')\n",
    "    \n",
    "plt.legend()\n",
    "plt.xlabel( 'log(C)' )                                                                                                      \n",
    "plt.ylabel( 'accuracy' )\n",
    "#plt.savefig('LogisticGridSearchCV_C.png' )\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
